#include "camera.h"
using namespace glm;
Camera::Camera(float x, float y, glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 cameraUp)
    : Pos(cameraPos), Front(cameraFront), Up(cameraUp), speed(2.5f), yaw(-90.0f), pitch(0.0f), fov(45.0f), viewPx(x), viewPy(y) {}
void Camera::reset()
{
    Pos = vec3(0.0, 0.0, 3.0);
    Front = vec3(0.0, 0.0, -1.0);
    Up = vec3(0.0, 1.0, 0.0);
    yaw = -90.0f;
    pitch = 0.0f;
    fov = 45.0f;
}
void Camera::setSpeed(float s)
{
    speed = s;
}

void Camera::moveForward()
{
    Pos += speed * normalize(vec3(Front.x, 0, Front.z));
}
void Camera::moveBackward()
{
    Pos -= speed * normalize(vec3(Front.x, 0, Front.z));
}
void Camera::moveLeft()
{
    Pos -= normalize(cross(Front, Up)) * speed;
}
void Camera::moveRight()
{
    Pos += normalize(cross(Front, Up)) * speed;
}

void Camera::moveUp()
{
    Pos += speed * Up;
}
void Camera::moveDown()
{
    Pos -= speed * Up;
}

void Camera::mouseMove(float sensitivity, float xoffset, float yoffset)
{
    xoffset *= sensitivity, yoffset *= sensitivity;
    yaw += xoffset;
    pitch += yoffset;
    if (pitch > 89.0f)
        pitch = 89.0f;
    if (pitch < -89.0f)
        pitch = -89.0f;
    glm::vec3 front = vec3(1.0f);
    front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
    front.y = sin(glm::radians(pitch));
    front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
    Front = normalize(front);
}

void Camera::mouseScroll(float xoffset, float yoffset)
{
    if (fov >= 1.0f && fov <= 45.0)
        fov -= yoffset;
    if (fov <= 1.0f)
        fov = 1.0f;
    if (fov >= 45.0)
        fov = 45.0;
}

mat4 Camera::projection() const
{
    return perspective(radians(fov), (float)viewPx / viewPy, 0.1f, 100.0f);
}

mat4 Camera::lookAt() const
{
    return glm::lookAt(Pos, Pos + Front, Up);
}